home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / LIBIP / TLC3FCT.C < prev    next >
C/C++ Source or Header  |  1999-09-11  |  7KB  |  180 lines

  1. /* 
  2.  * tlc3fct.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* TLC3FCT:     functions for TLC3 line structure analysis on top of PCC coding
  10.  *
  11.  *      FUNCTIONS:
  12.  *              TLC3STRUCTS, TLC3FEATS
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "pcc2.h"               /* header file for PCC programs */
  18.  
  19. /* TLC3STRUCTS: function reads through level 1 line list, finding
  20.  *            beginning of each connected structure, and returning
  21.  *              array of this list of <iAttr>.
  22.  *              usage: tlc3structs (attr, nAttr, &strct, &nStrct)
  23.  *
  24.  */
  25.  
  26. tlc3structs (attr, nAttr, strct, nStrct)
  27.      struct attributes *attr;   /* level 1 attributes */
  28.      register long nAttr;       /* no. of line structures in attr. array */
  29.      struct structures **strct; /* level 3 connected line structures */
  30.      long *nStrct;              /* no. of connected structures in image */
  31. {
  32.   register long iAttr,          /* incrementor for line list */
  33.     iStrct,                     /* incrementor for structure list */
  34.     iBranchBreak;               /* no. of remaining branches in start
  35.                                  * * or break code */
  36.   long nPts;                    /* no. x,y points in object */
  37.   double sumX, sumY;            /* sum of coordinates for centroid */
  38.  
  39. /* allocate memory for level 3 structures */
  40.   if ((*strct = (struct structures *)
  41.        calloc (nAttr, sizeof (struct structures))) == NULL) {
  42.     printf ("TLC3STRUCTS: CALLOC -- not enough memory");
  43.     return (-1);
  44.   }
  45.  
  46.   *nStrct = 0;
  47.   iBranchBreak = 0;
  48.  
  49. /* first find the tlc1 line index where each structure begins */
  50.  
  51.   for (iAttr = 0; iAttr < nAttr; iAttr++) {
  52.     if ((attr[iAttr].type >= EELINE && attr[iAttr].type <= ECLINE)
  53.         || attr[iAttr].type >= RLELINE && attr[iAttr].type <= RCCLINE) {
  54.  
  55.       if (iBranchBreak == 0) {
  56.         (*strct)[(*nStrct)++].iAttr = iAttr;
  57.  
  58.         /* set <iBranchCode> equal to remaining no. of branches for
  59.          * start or break code */
  60.         if (attr[iAttr].type >= EELINE && attr[iAttr].type <= ECLINE)
  61.           iBranchBreak = 0;
  62.         else if (attr[iAttr].type >= RLELINE
  63.                  && attr[iAttr].type <= RLCLINE)
  64.           iBranchBreak = 1;
  65.         else if (attr[iAttr].type >= RBELINE
  66.                  && attr[iAttr].type <= RBCLINE)
  67.           iBranchBreak = 2;
  68.         else if (attr[iAttr].type >= RCELINE
  69.                  && attr[iAttr].type <= RCCLINE)
  70.           iBranchBreak = 3;
  71.         else {
  72.           printf ("TLC3STRUCTS: error, not legal attr type\n");
  73.           return (-1);
  74.         }
  75.       }
  76.       else
  77.         iBranchBreak -= 1;
  78.     }
  79.   }
  80.  
  81. /* reallocate structure memory -- Note that in TLC2LOOP, this
  82.  * requires (nStrct + 1) elements in strct array */
  83.  
  84.   *strct = (struct structures *) realloc (*strct,
  85.                                 (*nStrct + 1) * sizeof (struct structures));
  86.   (*strct)[*nStrct].iAttr = 10000000;
  87.  
  88. /* now calculate level 3 attributes from level 1 */
  89.   for (iStrct = 0; iStrct < *nStrct; iStrct++) {
  90.     (*strct)[iStrct].nLines = (*strct)[iStrct].nEnds =
  91.       (*strct)[iStrct].nLoops = (*strct)[iStrct].width =
  92.       (*strct)[iStrct].length = (*strct)[iStrct].maxLength = 0;
  93.     sumX = sumY = 0.0;
  94.     nPts = 0;
  95.     (*strct)[iStrct].box.min.x = (*strct)[iStrct].box.min.y = 100000000;
  96.     (*strct)[iStrct].box.max.x = (*strct)[iStrct].box.max.y = -1;
  97.     for (iAttr = (*strct)[iStrct].iAttr;
  98.          (iAttr < (*strct)[iStrct + 1].iAttr && iAttr < nAttr); iAttr++) {
  99.       (*strct)[iStrct].nLines++;
  100.       if (attr[iAttr].type == EELINE)
  101.         (*strct)[iStrct].nEnds += 2;
  102.       else if (attr[iAttr].type == EBLINE || attr[iAttr].type == ECLINE
  103.                || attr[iAttr].type == BELINE || attr[iAttr].type == CELINE
  104.                || attr[iAttr].type == RLELINE || attr[iAttr].type == RBELINE
  105.                || attr[iAttr].type == RCELINE)
  106.         (*strct)[iStrct].nEnds++;
  107.       (*strct)[iStrct].width += attr[iAttr].width;
  108.       (*strct)[iStrct].length += attr[iAttr].length;
  109.       if (attr[iAttr].length > (*strct)[iStrct].maxLength)
  110.         (*strct)[iStrct].maxLength = attr[iAttr].length;
  111.       sumX += attr[iAttr].sumPt.x;
  112.       sumY += attr[iAttr].sumPt.y;
  113.       nPts += attr[iAttr].nPts;
  114.       if (attr[iAttr].box.min.x < (*strct)[iStrct].box.min.x)
  115.         (*strct)[iStrct].box.min.x = attr[iAttr].box.min.x;
  116.       if (attr[iAttr].box.min.y < (*strct)[iStrct].box.min.y)
  117.         (*strct)[iStrct].box.min.y = attr[iAttr].box.min.y;
  118.       if (attr[iAttr].box.max.x > (*strct)[iStrct].box.max.x)
  119.         (*strct)[iStrct].box.max.x = attr[iAttr].box.max.x;
  120.       if (attr[iAttr].box.max.y > (*strct)[iStrct].box.max.y)
  121.         (*strct)[iStrct].box.max.y = attr[iAttr].box.max.y;
  122.     }
  123.     (*strct)[iStrct].width /= (*strct)[iStrct].nLines;
  124.     (*strct)[iStrct].centroidX = sumX / (double) nPts;
  125.     (*strct)[iStrct].centroidY = sumY / (double) nPts;
  126.   }
  127.   return (0);
  128. }
  129.  
  130.  
  131. /* TLC3FEATS:   function determines level 3 attributes
  132.  *                    usage: tlc3feats (attr, nAttr, structs, nStructs)
  133.  *
  134.  */
  135.  
  136. tlc3feats (attr, nAttr, structs, nStructs)
  137.      struct attributes *attr;   /* level 1 attributes */
  138.      long nAttr;                /* no. level 1 attributes */
  139.      struct structures *structs;  /* level 3 attributes */
  140.      long nStructs;             /* no. level 3 attributes */
  141. {
  142.   long iStructs,                /* level 3 increment */
  143.     iAttr,                      /* level 1 increment */
  144.     iAttrEnd;                   /* end + 1 line 1 attribute in structure */
  145.  
  146.   for (iStructs = 0; iStructs < nStructs; iStructs++) {
  147.     structs[iStructs].nLines = structs[iStructs].nEnds = 0;
  148.     structs[iStructs].nLoops = structs[iStructs].length = 0;
  149.     structs[iStructs].width = structs[iStructs].maxLength = 0;
  150.     iAttrEnd = (iStructs + 1 < nStructs) ? structs[iStructs + 1].iAttr : nAttr;
  151.     structs[iStructs].box.min.x = structs[iStructs].box.min.y = 100000;
  152.     structs[iStructs].box.max.x = structs[iStructs].box.max.y = 0;
  153.     for (iAttr = structs[iStructs].iAttr; iAttr < iAttrEnd; iAttr++) {
  154.       if (attr[iAttr].length != 0) {
  155.         structs[iStructs].width += attr[iAttr].width;
  156.         structs[iStructs].length += attr[iAttr].length;
  157.         if (structs[iStructs].maxLength < attr[iAttr].length)
  158.           structs[iStructs].maxLength = attr[iAttr].length;
  159.         structs[iStructs].nLines++;
  160.         if (attr[iAttr].type == EELINE || attr[iAttr].type == EBLINE
  161.             || attr[iAttr].type == ECLINE || attr[iAttr].type == BELINE
  162.             || attr[iAttr].type == CELINE || attr[iAttr].type == RLELINE
  163.             || attr[iAttr].type == RBELINE || attr[iAttr].type == RCELINE)
  164.           structs[iStructs].nEnds++;
  165.       }
  166.       if (attr[iAttr].box.min.x < structs[iStructs].box.min.x)
  167.         structs[iStructs].box.min.x = attr[iAttr].box.min.x;
  168.       if (attr[iAttr].box.min.y < structs[iStructs].box.min.y)
  169.         structs[iStructs].box.min.y = attr[iAttr].box.min.y;
  170.       if (attr[iAttr].box.max.x > structs[iStructs].box.max.x)
  171.         structs[iStructs].box.max.x = attr[iAttr].box.max.x;
  172.       if (attr[iAttr].box.max.y > structs[iStructs].box.max.y)
  173.         structs[iStructs].box.max.y = attr[iAttr].box.max.y;
  174.     }
  175.     structs[iStructs].width = (long) ((double) structs[iStructs].width /
  176.                                    (double) structs[iStructs].nLines + 0.5);
  177.   }
  178.   return (0);
  179. }
  180.